Skip to main content

第41章 初等数论

初等数论是研究整数性质的数学分支,其内容在程序设计中有着广泛应用,如密码学、算法优化、数据校验等。

41.1 基本概念与性质

41.1.1 整除

定义:设aabb为整数,且 b0b≠0,若存在整数kk使得 a=b×ka=b ×k,则称 bb 整除aa(或aa能被bb整除),记作 bab \mid a。此时bbaa的约(因数),aabb的倍数。

性质

  1. aba \mid bbcb \mid c,则aca \mid c(传递性)。
  2. aba \mid baca \mid c,则对任意整数mmnn,有 a(m×b+n×c)a \mid (m ×b+n ×c)
  3. aba \mid bbab \mid a,则a=±ba= \pm b
  4. bab \mid a,则ba×kb \mid a \times kkk为任意整数)。

41.1.2 素数与合数

  • 素数(质数):大于1的整数,若除了1和自身外没有其他正约数,则称为素数(如2、3、5、7)。
  • 合数:大于1的非素数整数(如4、6、8、9)。
  • 特殊规定:1既不是素数也不是合数。

性质

  1. 大于2的素数都是奇数。
  2. 任何大于1的整数都能分解为素数的乘积(算术基本定理)。

41.1.3 最大公约数与最小公倍数

最大公约数(GCD):设aabb为整数,若dd是同时整除aabb的最大正整数,则dd称为aabb的最大公约数,记作gcd(a,b)\\gcd(a,b)

  • 性质:gcd(a,b)=gcd(b,amodb)\\gcd(a,b)=\gcd(b,a \bmod b)(辗转相除法的理论基础)。
  • 互质定义:若 gcd(a,b)=1\gcd(a, b)=1,则称aabb互质(互素)。

最小公倍数(LCM):设aabb为正整数,若mm是同时是aabb的最小正倍数,则mm称为aabb的最小公倍数,记作lcm(a,b)\text{lcm}(a, b)

  • 性质:对任意正整数aabba×b=gcd(a,b)×lcm(a,b)a ×b = \gcd(a, b) × \text{lcm}(a, b)

41.2 核心算法与实现

41.2.1 辗转相除法(欧几里得算法)求GCD

// 迭代版:求a和b的最大公约数(a、b为非负整数,且不同时为0)
int gcd(int a,int b){
while(b!=0){
int temp = b;
b = a % b;
a = temp;
}
return a;
}

// 递归版本
int gcdRecursive (int a, int b) {
if(b == 0) return a;
return gcdRecursive(b, a % b);
}

41.2.2 最小公倍数(LCM)的计算

// 求a和b的最小公倍数(a、b为正整数)
int lcm(int a,int b){
return a / gcd(a, b) * b;// 先除后乘,避免溢出
}

41.2.3 素数判定(试除法)

判断一个数nn是否为素数,只需检查2n2 \sim \sqrt{n}之间的整数能否整除nn

// 判断n是否为素数(n≥2)
bool isPrime(int n){
if (n <= 1) return false;
if (n == 2) return true;
if(n % 2 == 0)return false;// 偶数一定不是素数
for(int i=3;i*i<=n;i+=2){// 只检查奇数
if(n % i == 0) return false;
}
return true;
}

41.2.4 埃氏筛法(筛选素数)

埃氏筛法是筛选1n1 \sim n所有素数的算法,时间复杂度O(nloglogn)O(n\log\log n)

// 返回标记数组,isPrime[i]为true代表i是素数
vector<bool> sieveOfEratosthenes (int n) {
vector<bool> isPrime (n + 1, true);
isPrime[0] = isPrime[1] = false;
for (int p = 2;p * p <= n; p++) {
if(isPrime[p]){
for (int i = p * p;i <= n;i += p){
isPrime[i] = false;
}
}
}
return isPrime;
}

41.2.5 线性筛法(欧拉筛法)

线性筛时间复杂度O(n)O(n),每个合数只会被其最小质因数标记一次,无重复操作。

// 线性筛,返回1~n内所有素数列表
vector<int> linearSieve (int n) {
vector<bool> isComposite(n + 1,false);
vector<int> primes;// 存储素数
for (int i=2;i<=n; ++i) {
if(!isComposite[i]){
primes.push_back(i);// i是素数
}
// 用已找到的素数筛除合数
for (int p : primes){
if(i * p > n) break;
isComposite[i * p] = true;
if(i % p == 0)break;// p是i最小质因数,停止循环
}
}
return primes;
}

优势

  1. 不会重复标记合数(如6仅被2标记,不会再被3标记),大数据效率更高;
  2. 可同步记录每个数字最小质因数,方便质因数分解。

41.2.6 分解质因数

算术基本定理:任意大于1整数可唯一分解为素数乘积。

#include <map>
// 将n分解,返回{质因数:指数}映射
map<int, int> primeFactorization (int n){
map<int, int> factors;
// 处理2的倍数
while (n % 2 == 0){
factors[2]++;
n /= 2;
}
// 处理奇数因子
for (int i=3;i*i<=n;i += 2){
while (n % i == 0){
factors[i]++;
n /= i;
}
}
// 剩余大于2的素数
if (n > 2){
factors[n]++;
}
return factors;
}

41.3 同余与模运算

41.3.1 同余定义

若整数aabb除以mm余数相同,则称aabbmm同余,记作 ab(modm)a \equiv b \pmod{m},等价 m(ab)m \mid (a-b)

41.3.2 模运算性质

  1. (a+b)modm=[(amodm)+(bmodm)]modm(a+b) \bmod m = [(a \bmod m)+(b \bmod m)] \bmod m
  2. (ab)modm=[(amodm)(bmodm)+m]modm(a-b) \bmod m = [(a \bmod m)-(b \bmod m)+m] \bmod m(加mm避免负数)
  3. (a×b)modm=[(amodm)×(bmodm)]modm(a ×b) \bmod m = [(a \bmod m) ×(b \bmod m)] \bmod m

快速幂(模幂运算)

高效计算abmodma^b \bmod m,时间O(logb)O(\log b)

long long fastPower(long long a,long long b,long long m){
long long result=1;
a %= m;
while (b > 0){
if(b % 2 == 1){
result = (result * a) % m;
}
a = (a * a) % m;
b /= 2;
}
return result;
}

41.3.3 同余方程简介

最简同余方程 axb(modm)a x \equiv b \pmod{m},有解充要条件:gcd(a,m)b\gcd(a, m) \mid b。 若gcd(a,m)=1\gcd(a, m)=1,存在模逆元 aϕ(m)1(modm)a^{\phi(m)-1} \pmod{m}

41.4 常用数论定理

41.4.1 算术基本定理

任意大于1整数nn可唯一分解:

n=p1k1×p2k2××pmkmn=p_{1}^{k_{1}} × p_{2}^{k_{2}} × \dots × p_{m}^{k_{m}}

p1<p2<<pmp_1<p_2<\dots<p_m为素数,kik_i为对应指数。

41.4.2 唯一分解定理推论

a=p1a1p2a2pkaka=p_1^{a_1}p_2^{a_2}\dots p_k^{a_k}b=p1b1p2b2pkbkb=p_1^{b_1}p_2^{b_2}\dots p_k^{b_k}

gcd(a,b)=p1min(a1,b1)p2min(a2,b2)pkmin(ak,bk)\\gcd(a,b)=p_1^{\min(a_1,b_1)}p_2^{\min(a_2,b_2)}\dots p_k^{\min(a_k,b_k)} lcm(a,b)=p1max(a1,b1)p2max(a2,b2)pkmax(ak,bk)\text{lcm}(a,b)=p_1^{\max(a_1,b_1)}p_2^{\max(a_2,b_2)}\dots p_k^{\max(a_k,b_k)}
  • 因数个数公式:nn分解后指数k1,k2kmk_1,k_2\dots k_m,因数总数(k1+1)(k2+1)(km)(k_1+1)(k_2+1)\dots(k_m)。 示例:12=22×3112=2^2×3^1,因数个数(2+1)(1+1)=6(2+1)(1+1)=6

41.4.3 欧拉定理

gcd(a,m)=1\gcd(a, m)=1,则 aϕ(m)1(modm)a^{\phi(m)} \equiv 1 \pmod{m}ϕ(m)\phi(m)代表1m1\sim m中和mm互质数字总数。

41.4.4 费马小定理

pp是素数,且aa不被pp整除,则 ap11(modp)a^{p-1} \equiv 1 \pmod{p}。 费马小定理是欧拉定理mm为素数时的特例(ϕ(p)=p1\phi(p)=p-1)。

41.5 注意事项

  1. 数据溢出:大数运算使用long long替代int
  2. 边界:0不能作为除数;1非素数;2是唯一偶素数。
  3. 模负数:C++中负数取模结果为负,需(xmodm+m)modm(x \bmod m + m) \bmod m转正。
  4. 筛法选择:小规模判断素数用试除,大范围批量筛素数用线性筛。

本章41章提取完毕,下一章:第42章 数组模拟高精度计算